/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package twoTeam;

import ants.*;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.ListIterator;
import javax.swing.JFrame;

/**
 *
 * @author Sagrevyum
 */
public class cliente {

    static int foodRest;
    static LinkedList moves;
    float feromonaC[][];
    float feromonaE[][];
    float feromonaD[][];
    float feromonaA[][];

    public static void main(String[] args) throws ClassNotFoundException, IOException {

        cliente client = new cliente();

    }

    cliente() throws ClassNotFoundException, IOException {
        Socket socket = new Socket("localhost", 5000);
        InputStream aux = socket.getInputStream();
        ObjectInputStream entradaObjetos = new ObjectInputStream(aux);
        OutputStream aux2 = socket.getOutputStream();
        ObjectOutputStream os = new ObjectOutputStream(aux2);
        Conocimiento[] conocimientoHormiga;
        // Leer estado inicial
        Inicial mapa;
        mapa = (Inicial) entradaObjetos.readObject();
        System.out.println("Recibi el mapa");

        // Inicializar las matrices de las feromonas con las dimesiones del mapa
        feromonaC = new float[2 * (mapa.n + 2)][2 * (mapa.m + 2)];
        feromonaE = new float[2 * (mapa.n + 2)][2 * (mapa.m + 2)];
        feromonaD = new float[2 * (mapa.n + 2)][2 * (mapa.m + 2)];
        feromonaA = new float[2 * (mapa.n + 2)][2 * (mapa.m + 2)];

        // Crea los paneles


        JFrame aplicacion;
        int l = 700 / ((mapa.n + 2) * 2);
        /*
        aplicacion = new JFrame("Comida : Cliente " + mapa.numCli);
        Gradiente comida = new Gradiente(mapa.n * 2, mapa.m * 2, l, 1, feromonaC);
        aplicacion.add(comida);
        aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        aplicacion.setSize(((mapa.m + 2) * 2 * l) + 20, 700);
        aplicacion.setVisible(true);
        aplicacion = new JFrame("Exploracion : Cliente " + mapa.numCli);
        Gradiente exploracion = new Gradiente(mapa.n * 2, mapa.m * 2, l, 0, feromonaE);
        aplicacion.add(exploracion);
        aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        aplicacion.setSize(((mapa.m + 2) * 2 * l) + 20, 700);
        aplicacion.setVisible(true);
        */
        aplicacion = new JFrame("Ataque: Cliente " + mapa.numCli);
        Gradiente ataque = new Gradiente(mapa.n * 2, mapa.m * 2, l, 2, feromonaA);
        aplicacion.add(ataque);
        aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        aplicacion.setSize(((mapa.m + 2) * 2 * l) + 20, 700);
        aplicacion.setVisible(true);
        /*
        aplicacion = new JFrame("Distancia : Cliente " + mapa.numCli);
        Gradiente distancia = new Gradiente(mapa.n * 2, mapa.m * 2, l, 2, feromonaD);
        aplicacion.add(distancia);
        aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        aplicacion.setSize(((mapa.m + 2) * 2 * l) + 20, 700);
        aplicacion.setVisible(true);
        */

        ArrayList lista;
        lista = new ArrayList();
        int k = 1;
        //System.out.println("Hay " + mapa.getExploradoras() + " exploradoras");
        for (int x = 0; x < mapa.getExploradoras(); x++) {
            lista.add(new Hormiga(k++, 0, mapa.n, mapa.m,mapa.numCli));
        }
        for (int x = 0; x < mapa.getGuerreras(); x++) {
            lista.add(new Hormiga(k++, 1, mapa.n, mapa.m,mapa.numCli));
        }
        for (int x = 0; x < mapa.getObreras(); x++) {
            lista.add(new Hormiga(k++, 2, mapa.n, mapa.m,mapa.numCli));
        }



        while (true) {
            // Recibir vistas
            AntsView vista;
            FinalView tmpFinalView;
            HashMap conocidos;
            Knowledge conocimiento;

            //vista = (AntsView) entradaObjetos.readObject();

            tmpFinalView = (FinalView) entradaObjetos.readObject();
            conocidos = tmpFinalView.returnConocimientos();
            vista = tmpFinalView.returnView();

            // leer primer conocimiento
            for (int x = 1; x < k; x++) {
                if (conocidos.containsKey(x)) {
                    Hormiga temp;
                    temp = (twoTeam.Hormiga) lista.get(x-1);
                    conocimientoHormiga = (Conocimiento[]) conocidos.get(x);
                    if (temp.conocimiento != null) {
                        temp.conocimientoMerge(conocimientoHormiga);
                    } else {
                        temp.setConocimiento(conocimientoHormiga);
                    }
                }
            }
            conocimiento = tmpFinalView.returnKnowledge();
            // Evaporacion de las feronomas
            this.evaporacion();
            //Repintar los paneles de feromona
            /*
             * exploracion.repaint(); comida.repaint(); distancia.repaint();
             *
             */
            ataque.repaint();
            // Se da a las hormigas sus vistas y se determina su movimiento
            // Logica
            MoveList movimientos = new MoveList(); // Lista de movimientos para mandar al server
            ListIterator itr = lista.listIterator();
            while (itr.hasNext()) {
                Hormiga ant = (Hormiga) itr.next();
                Perspective p = (Perspective) vista.perspectiva.get(ant.id);
                Perspective_k p_k = (Perspective_k) conocimiento.perspectiva.get(ant.id);
                if (p.movil) {
                    float[][] fC = new float[3][3];
                    for (int y = 0; y < 3; y++) {
                        for (int x = 0; x < 3; x++) {
                            fC[y][x] = feromonaC[ant.pos.y + y - 1][ant.pos.x + x - 1];
                        }
                    }
                    float[][] fE = new float[3][3];
                    for (int y = 0; y < 3; y++) {
                        for (int x = 0; x < 3; x++) {
                            fE[y][x] = feromonaE[ant.pos.y + y - 1][ant.pos.x + x - 1];
                        }
                    }
                    float[][] fD = new float[3][3];
                    for (int y = 0; y < 3; y++) {
                        for (int x = 0; x < 3; x++) {
                            fD[y][x] = feromonaD[ant.pos.y + y - 1][ant.pos.x + x - 1];
                        }
                    }
                    float[][] fA= new float[3][3];
                    for (int y = 0; y < 3; y++) {
                        for (int x = 0; x < 3; x++) {
                            fA[y][x] = feromonaA[ant.pos.y + y - 1][ant.pos.x + x - 1];
                        }
                    }
                    Respuesta r = ant.getMovimiento((Perspective) vista.perspectiva.get(ant.id), fC, fE, fD, fA, p_k);

                    if (r.direccion != 4) {
                        movimientos.agregar(new Move(ant.id, r.direccion));
                    }

                    for (int y = 0; y < 3; y++) {
                        for (int x = 0; x < 3; x++) {
                            feromonaC[ant.pos.y + y - 1][ant.pos.x + x - 1] += r.dC[y][x];
                            if (feromonaC[ant.pos.y + y - 1][ant.pos.x + x - 1] > 1.0f) {
                                feromonaC[ant.pos.y + y - 1][ant.pos.x + x - 1] = 1.0f;
                            }
                            feromonaE[ant.pos.y + y - 1][ant.pos.x + x - 1] += r.dE[y][x];
                            if (feromonaE[ant.pos.y + y - 1][ant.pos.x + x - 1] > 1.0f) {
                                feromonaE[ant.pos.y + y - 1][ant.pos.x + x - 1] = 1.0f;
                            }
                            feromonaD[ant.pos.y + y - 1][ant.pos.x + x - 1] += r.dD[y][x];
                            if (feromonaD[ant.pos.y + y - 1][ant.pos.x + x - 1] > 1.0f) {
                                feromonaD[ant.pos.y + y - 1][ant.pos.x + x - 1] = 1.0f;
                            }
                            feromonaA[ant.pos.y + y - 1][ant.pos.x + x - 1] += r.dA[y][x];
                            if (feromonaA[ant.pos.y + y - 1][ant.pos.x + x - 1] > 1.0f) {
                                feromonaA[ant.pos.y + y - 1][ant.pos.x + x - 1] = 1.0f;
                            }
                        }
                    }
                    ant.move(r.direccion);
                }
            }

            // Mandar movimientos
            os.writeObject(movimientos);
            conocidos = (HashMap) entradaObjetos.readObject();
            //System.out.println("Recibi el conocimiento"); 


            for (int x = 1; x < k; x++) {
                if (conocidos.containsKey(x)) {
                    Hormiga temp;
                    temp = (twoTeam.Hormiga) lista.get(x-1);
                    conocimientoHormiga = (Conocimiento[]) conocidos.get(x);
                    if (temp.conocimiento != null) {

                        temp.conocimientoMerge(conocimientoHormiga);

                    } else {
                        temp.setConocimiento(conocimientoHormiga);
                    }

                }


            }



            //System.out.println("Mande los movimientos");
            /*
             * try { Thread.sleep(300); } catch (Exception e) { }
             *
             */
        }

    }

    private void evaporacion() {
        for (int x = 0; x < feromonaE.length; x++) {
            for (int y = 0; y < feromonaE[x].length; y++) {
                feromonaE[x][y] *= 0.98;
                feromonaC[x][y] *= 0.98;
                feromonaA[x][y] *= 0.99;
            }
        }
    }
}